#include "udpserver.h"

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SRC_PORT        10002
#define DEST_PORT       10001

#define	MAX_BUF_LEN     1024

#define GROUP "226.0.0.10"//"239.0.0.2"//

typedef struct {
    int socketfd;
	struct sockaddr_in serveraddr;
	struct sockaddr_in clientaddr;
	struct ip_mreq group;
}m_socket_t;

int udp_send_data(m_socket_t *socket, char *buf, int len)
{
    int32_t ret = 0;
    uint32_t offset = 0;

    if(buf == NULL || len < MAX_BUF_LEN){
	    return -1;
	}

	memset(&socket->clientaddr, 0, sizeof(struct sockaddr_in));
    socket->clientaddr.sin_family      = AF_INET;
    socket->clientaddr.sin_port        = htons(DEST_PORT);
    socket->clientaddr.sin_addr.s_addr = inet_addr(GROUP);
    
    while(offset < len){    
        ret = sendto(socket->socketfd, 
                     buf, 
                     MAX_BUF_LEN, 
                     0, 
                     (struct sockaddr *)&socket->clientaddr, 
                     sizeof(struct sockaddr_in));
        if(ret != MAX_BUF_LEN){
            printf("Frame Sent %d.", ret);
        }
        
        offset += ret;
    }
    
    return 0;
}

int main(int argc, char *argv[])
{
    int ret = 0;
    unsigned int length = 0;
    m_socket_t udpsocket;
    char *udp_send;
    int count = 0;
    
	udpsocket.socketfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (udpsocket.socketfd == -1) {
		perror("socket error");
		return -1;
	}
	
	memset(&udpsocket.serveraddr, 0, sizeof(struct sockaddr_in));
	udpsocket.serveraddr.sin_family         = AF_INET;
	udpsocket.serveraddr.sin_port           = htons(SRC_PORT);
	udpsocket.serveraddr.sin_addr.s_addr    = htonl(INADDR_ANY);

	ret = bind(udpsocket.socketfd, (struct sockaddr *)&udpsocket.serveraddr, \
	                     sizeof(struct sockaddr_in));
	if (ret == -1) {
		perror("bind error");
		close(udpsocket.socketfd);
		return 0;
	}

	memset(&udpsocket.group, 0, sizeof(struct ip_mreq));
	udpsocket.group.imr_multiaddr.s_addr = inet_addr(GROUP);
    udpsocket.group.imr_interface.s_addr = htonl(INADDR_ANY);
    if (setsockopt(udpsocket.socketfd, IPPROTO_IP, IP_MULTICAST_IF,
                    &udpsocket.group, sizeof (struct ip_mreq)) == -1) {
        perror("group error");
        return -1;
    }
    
    udp_send = malloc(1920 * 1080 * 4);
    if(udp_send == NULL){
        perror("malloc error");
        return -1;
    }
    
    FILE *testfd = NULL;
    
    testfd = fopen("videoDdata.bmp", "r");
    if(testfd == NULL){
        printf("the open the file is failure \n");
        return -1;
    }
    
    fseek(testfd, 0l, SEEK_END);
    length = ftell(testfd);
    fseek(testfd, 0l, SEEK_SET);
    int offset = 0;
    while(1){
        ret = fread(&udp_send[offset], 1, MAX_BUF_LEN, testfd);
        if(ret == 0){
            printf("file length: %d \n", offset);
            break;
        }
        
        offset += ret;
    }
    
unsigned int socklen = sizeof(struct sockaddr_in);

	while(1){
        ret = udp_send_data(&udpsocket, udp_send, length);
        printf("%d:UDP Sending %d Byte(s) Data...\n", count++, length);
        sleep(1);
#if 0
        memset(recmsg, 0, sizeof(recmsg));
        ret = recvfrom(udpsocket.socketfd, recmsg, 255, 0, (struct sockaddr *) &udpsocket.serveraddr, &socklen);
        if (ret < 0) {      
            printf ("recvfrom err in udptalk!\n");         
        } else {      
        /* 成功接收到数据报 */ 
            recmsg[ret] = 0;      
            printf("Recv Ok! %s",recmsg);
        }
#endif
	}
	
	free(udp_send);
	
	fclose(testfd);
	close(udpsocket.socketfd);
	
    return 0;
}





